#!/bin/bash

script_dir=$(dirname "$(realpath "${BASH_SOURCE[0]}")")
if [ -f $script_dir/rpcf/showapp.sh ]; then
    # in the installation directory
    cmddir=$script_dir/rpcf 
    tooldir=
elif [ -f $script_dir/showapp.sh ]; then
    # in the dev tree
    cmddir=$script_dir
    tooldir=$script_dir/../../tools/
else
    echo Error cannot find rpc-frmwrk installation
    exit 1
fi

updattr=${cmddir}/updattr.py

if [[ "$script_dir" == "/usr/bin" ]]; then
    cfgPath="/etc/rpcf"
elif [[ "$script_dir" == "/usr/local/bin" ]]; then
    cfgPath="/usr/local/etc/rpcf"
fi
#echo cmddir=$cmddir
source ${cmddir}/appfuncs.sh

# rpcfctl - rpc-frmwrk Control Utility
# Usage: rpcfctl <start|stop|status|list> [appname]

function usage() {
    echo you can 'man rpcfctl' for detailed introduction.
}

if [[ $# -lt 1 ]]; then
    echo Error invalid parameters
    exit 1
fi

cmd="$1"
shift

function is_app_online()
{
    if check_appreg_mount; then
        if [ -d ${rootdir} ]; then
            owner_stream=`python3 $updattr -v ${rootdir}/apps/$1/owner_stream`
            if [[ -z "$owner_stream" ]] || (( $owner_stream == 0 )); then
                ret=1        
            else
                ret=0
            fi
        fi
        undo_check_appreg_mount
    else
        ret=1
    fi
    return $ret
}

case "$cmd" in
    config | cfg)
        if [[ -f $tooldir/rpcfg.py ]]; then
            python3 $tooldir/rpcfg.py $@
        elif [[ -f $cmddir/rpcfg.py ]]; then
            python3 $cmddir/rpcfg.py $@
        else
            echo "Error cannot find rpcfg.py"
        fi
        ;;
    start)
        if [[ $# -lt 1 ]]; then
            echo "Error: appname required for 'start'"
            usage
            exit 1
        fi
        for appname in "$@"; do
            echo "Starting application: $appname"
            if is_app_online $appname; then
                echo "Error $appname is still running"
                exit 1
            fi
            if [[ "$appname" == "appmonsvr1" ]]; then
                if ! rpcfctl clearmount; then
                    exit 1
                fi
            fi
            cmdline=`bash $cmddir/getpv.sh $appname cmdline | awk -F: '{print $2}'`
            working_dir=`bash $cmddir/getpv.sh $appname working_dir | awk -F: '{print $2}'`
            if [[ "x$cmdline" == "x" ]] || [[ "x$working_dir" == "x" ]]; then
                echo "Error bad command line to start $appname"
                exit 1
            fi
            if [ ! -d $working_dir ]; then
                echo "Error bad working directory to start $appname"
                exit 1
            fi
            cd $working_dir || exit 1
            echo $cmdline
            setsid -f $cmdline > /dev/null 2>&1
        done
        ;;
    stop)
        if [[ $# -lt 1 ]]; then
            echo "Error: appname required for 'stop'"
            usage
            exit 1
        fi
        for appname in "$@"; do
            echo "Stopping application: $appname"
            if ! is_app_online $appname; then
                echo "Error $appname is already stopped"
                exit 1
            fi
            if [[ "x$appname" == "xappmonsvr1" ]]; then
                if check_appreg_mount; then
                    if [ -d ${rootdir}/../appreg ]; then
                        rootdir=$(dirname $rootdir)
                        fusermount3 -u ${rootdir}
                        echo
                        exit 0
                    fi
                    undo_check_appreg_mount
                fi
            fi
            pid=`bash $cmddir/getpv.sh $appname pid | awk -F: '{print $2}'`
            if [[ "x$pid" != "x" ]]; then
                if ! kill -2 $pid; then
                    if check_appreg_mount; then
                        python3 $updattr -u 'user.regfs' "$(jsonval i 0)" ${rootdir}/apps/$appname/owner_stream > /dev/null
                        undo_check_appreg_mount
                    fi
                fi
            else
                echo Error failed to stop $appname
            fi
        done
        ;;
    kill)
        if [[ $# -lt 1 ]]; then
            echo "Error: appname required for 'stop'"
            usage
            exit 1
        fi
        appname="$1"
        echo "Stopping application: $appname"
        if ! is_app_online $appname; then
            echo "Error $appname is already stopped"
            exit 1
        fi
        pid=`bash $cmddir/getpv.sh $appname pid | awk -F: '{print $2}'`
        kill -9 $pid
        ;;
    restart)
        if [[ $# -lt 1 ]]; then
            echo "Error: appname required for 'restart'"
            usage
            exit 1
        fi
        appname="$1"
        bash $script_dir/rpcfctl stop $appname
        bash $script_dir/rpcfctl start $appname
        ;;
    status)
        if [[ $# -lt 1 ]]; then
            echo "Error: appname required for 'status'"
            usage
            exit 1
        fi
        appname="$1"
        echo "Status of application: $appname"
        bash $cmddir/showapp.sh $appname
        ;;
    list)
        echo "Listing all managed applications"
        bash $cmddir/listapps.sh
        ;;
    startall)
        if ! bash rpcfctl start appmonsvr1; then
            echo failed to start appmonsvr1, quit
            exit 1
        fi
        bash rpcfctl start loggersvr1
        bash rpcfctl start timer1
        bash rpcfctl start rpcrouter1
        if check_appreg_mount; then
            pushd ${rootdir}/apps
            arrApps=$(ls -d * )
            for skip in appmonsvr1 timer1 loggersvr1 rpcrouter1; do
                arrApps=$(echo "$arrApps" | tr ' ' '\n' | grep -vx "$skip" | tr '\n' ' ')
            done
            arrApps=$(echo "$arrApps") # Remove trailing spaces
            for appName in $arrApps; do
                if [ "x$appName" != "x" ]; then
                    bash $script_dir/rpcfctl start $appName
                fi
            done
            popd
            undo_check_appreg_mount
        fi
        ;;
    stopall)
        if check_appreg_mount; then
            pushd ${rootdir}/apps
            arrApps=$(ls -d * )
            for skip in appmonsvr1 timer1 loggersvr1 rpcrouter1; do
                arrApps=$(echo "$arrApps" | tr ' ' '\n' | grep -vx "$skip" | tr '\n' ' ')
            done
            arrApps=$(echo "$arrApps") # Remove trailing spaces
            for appName in $arrApps; do
                if [ "x$appName" != "x" ]; then
                    bash $script_dir/rpcfctl stop $appName
                fi
            done
            popd
            undo_check_appreg_mount
        fi
        bash rpcfctl stop rpcrouter1
        bash rpcfctl stop timer1
        bash rpcfctl stop loggersvr1
        bash rpcfctl stop appmonsvr1
        ;;
    restartall)
        echo "stopping all the applications..."
        bash rpcfctl stopall
        echo "starting all the applications..."
        bash rpcfctl startall
        ;;
    addapp | add)
        if [[ $# -lt 1 ]]; then
            echo "Error: appname required for 'addapp/add'"
            usage
            exit 1
        fi
        if bash $cmddir/addapp.sh $@; then
            if is_app_online loggersvr1; then
                rpcf_sendlog -f rpcfctl -l 254 -t INFO -n rpcfctl -p $$ "Added application $@ by rpcfctl"
            fi
        fi
        ;;
    rmapp | rm)
        if [[ $# -lt 1 ]]; then
            echo "Error: appname required for 'rmapp/rm' command"
            usage
            exit 1
        fi
        if is_app_online $1; then
            echo Error: please stop the application before removal.
            exit 1
        fi
        if bash $cmddir/rmapp.sh $@; then
            if is_app_online loggersvr1; then
                rpcf_sendlog -f rpcfctl -l 270 -t INFO -n rpcfctl -p $$ "Removed application(s) $@ by rpcfctl"
            fi
        fi
        ;;
    cloneapp)
        cmdline="rpcfctl cloneapp <src app> <dest app>"
        if [[ $# -lt 2 ]]; then
            echo Error missing parameters
            echo $cmdline
            exit 1
        fi
        if bash $cmddir/cloneapp.sh $@;then
            if is_app_online loggersvr1; then
                rpcf_sendlog -f rpcfctl -l 270 -t INFO -n rpcfctl -p $$ "cloned application(s) $2 from $1 by rpcfctl"
            fi
        fi
        ;;
    showapp)
        if [[ $# -lt 1 ]]; then
            echo "Error: appname required for 'showapp'"
            usage
            exit 1
        fi
        bash $cmddir/showapp.sh $1;
        ;;

    showpoint)
        if [[ $# -lt 2 ]]; then
            echo "Error: <appname> and <point name> required for 'showapp'"
            usage
            exit 1
        fi
        bash $cmddir/showpoint.sh $1 $2
        ;;
    addpoint)
        bash $cmddir/addpoint.sh $@
        ;;
    rmpoint)
        bash $cmddir/rmpoint.sh $@
        ;;
    setpv)
        bash $cmddir/setpv.sh $@
        ;;
    getpv)
        bash $cmddir/getpv.sh $@
        ;;
    setattr)
        bash $cmddir/setattr.sh $@
        ;;
    getattr)
        if check_appreg_mount; then
            pushd $rootdir > /dev/null
            get_attr_value $@
            ret=$?
            popd > /dev/null
            undo_check_appreg_mount
            exit $ret
        fi
        ;;
    addlink)
        bash $cmddir/addlink.sh $@
        ;;
    rmlink)
        bash $cmddir/rmlink.sh $@
        ;;
    initappreg)
        echo Warning 'initappreg' will clear the app registry,
        if ! bash rpcfctl clearmount; then
            echo initappreg fails
            exit $?
        fi
        bash $cmddir/initappreg.sh $@
        ;;
    initusereg)
        echo "Warning 'initusereg' will clear the user registry"
        bash $cmddir/inituser.sh
        ;;
    initsvr)
        bash $cmddir/inituser.sh && bash $cmddir/initappreg.sh
        ;;
    initcli)
        authmech=`rpcfctl authmech | tr -d ' \t\n\r'`
        if [[ "x$xauthmech" == "xSimpAuth" ]] ||
            [[ "x$xauthmech" == "xOAuth2" ]]; then
            regfsmnt -i $HOME/rpcf/clientreg.dat
            rpcfctl genkeys openssl 1 1
            rpcfctl genkeys gmssl 1 1
        fi
        ;;
    importkey | import)
        cmdline="rpcfctl importkey <openssl|gmssl> <private key file> <public cert file> [<cacert file>]"
        if [[ $# -lt 3 ]]; then
            echo "Error: Missing argument" 
            echo $cmdline
            exit 1
        fi
        if [[ "x$1" == "xopenssl" ]]; then
            targetdir=$HOME/.rpcf/openssl
        elif [[ "x$1" == "xgmssl" ]]; then
            targetdir=$HOME/.rpcf/gmssl
        else
            echo Error: Unknown cryptography type
            echo $cmdline
            exit 1
        fi

        if [[ ! -d $targetdir ]]; then
            mkdir -p $targetdir || exit 1
        fi
        src=$(realpath $2)
        dest=$(realpath $targetdir/$(basename $2))
        if [[ "$src" != "$dest" ]]; then
            cp "$2" "$targetdir/" || exit 1
            chmod 600 "$targetdir/$(basename $2)"
        fi
        src=$(realpath $3)
        dest=$(realpath $targetdir/$(basename $3))
        if [[ "$dest" != "$src" ]]; then
            cp "$3" "$targetdir/" || exit 1
            chmod 644 "$targetdir/$(basename $3)"
        fi
        if [[ "x$4" != "x" ]]; then
            src=$(realpath $4)
            dest=$(realpath $targetdir/$(basename $4))
            if [[ "$src" != "$dest" ]]; then
                cp "$4" "$targetdir/" || exit 1
                chmod 644 "$targetdir/$(basename $4)"
            fi
            caroot="$targetdir/$(basename $4)"
        fi
        bRoot="false"
        drvpath=$cfgPath/drver.json
        if [[ "$script_dir" == "/usr/bin" ]] || [[ "$script_dir" == "/usr/local/bin" ]]; then
            bRoot="true"
        else
            echo Error: unable to find driver.json to update
            exit 1
        fi
        if [[ "$bRoot" == "false" ]]; then
            SUDOCMD=
        else
            if which sudo; then
                SUDOCMD=sudo
            fi
        fi
        echo Updating key setting requires root privilige.
        if $SUDOCMD python3 $cmddir/updatekeys.py $drvpath $1 $targetdir/$(basename $2) $targetdir/$(basename $3) $caroot; then
            echo "Imported keys to $targetdir successfully."
            echo "rpc-frmwrk will use the newly imported key for SSL connection"
            echo "And don't forget to update your web server configuration if WebSocket is enabled "
        fi
        ;;
    genkeys)
        # generate self-signed openssl RSA key
        cmdline="rpcfctl genkeys <openssl|gmssl> <#client keys> <#server keys> [<DNS name>]"
        if [[ $# -lt 3 ]]; then
            echo "Error: Missing argument" 
            echo $cmdline
            exit 1
        fi
        if [[ "x$1" == "xopenssl" ]]; then
            if bash $cmddir/opensslkey.sh $HOME/.rpcf/openssl $2 $3 $4; then
                clidx=`cat $HOME/.rpcf/openssl/clidx`
                svridx=`cat $HOME/.rpcf/openssl/svridx`
                echo Successfully generated OpenSSL key/cert to $HOME/.rpcf/openssl
                echo server key/cert package is serverkeys-$svridx.tar.gz
                echo client key/cert package is clientkeys-$clidx.tar.gz
            else
                echo Error failed to generate OpenSSL key/cert
            fi
        elif [[ "x$1" == "xgmssl" ]]; then
            if bash $cmddir/gmsslkey.sh $HOME/.rpcf/gmssl $2 $3; then
                clidx=`cat $HOME/.rpcf/gmssl/clidx`
                svridx=`cat $HOME/.rpcf/gmssl/svridx`
                echo Successfully generated GmSSL key/cert to $HOME/.rpcf/gmssl
                echo server key/cert package is serverkeys-$svridx.tar.gz
                echo client key/cert package is clientkeys-$clidx.tar.gz
            else
                echo Error failed to generate GmSSL key/cert
            fi
        fi
        ;;
    printcert)
        cmdline="rpcfctl printcert <openssl|gmssl> <cert file>"
        if [[ $# -lt 2 ]]; then
            echo "Error: Missing argument" 
            echo $cmdline
            exit 1
        fi
        if [[ "x$1" == "xopenssl" ]]; then
            openssl x509 -inform pem -noout -text -in "$2"
        elif [[ "x$1" == "xgmssl" ]]; then
            gmssl certparse < "$2"
        else
            echo invalid cryptography type $1
        fi
        ;;
    adduser)
        cmdline="rpcfctl adduser <user name> [<user id>]"
        if [[ $# -lt 1 ]]; then
            echo "Error: Missing argument" 
            echo $cmdline
            exit 1
        fi
        bash $cmddir/rpcfaddu.sh $@
        ;;
    rmuser)
        cmdline="rpcfctl rmuser <user name>"
        if [[ $# -lt 1 ]]; then
            echo "Error: Missing argument" 
            echo $cmdline
            exit 1
        fi
        bash $cmddir/rpcfrmu.sh $@
        ;;
    showuser)
        cmdline="rpcfctl showuser <user name>"
        if [[ $# -lt 1 ]]; then
            echo "Error: Missing argument" 
            echo $cmdline
            exit 1
        fi
        bash $cmddir/rpcfshow.sh -u $1
        ;;
    listuser)
        cmdline="rpcfctl listuser"
        bash $cmddir/rpcfshow.sh -l
        ;;
    joingroup)
        cmdline="rpcfctl joingroup <group name> <user name>"
        if [[ $# -lt 2 ]]; then
            echo "Error: Missing argument" 
            echo $cmdline
            exit 1
        fi
        bash $cmddir/rpcfmodu.sh -g $1 $2
        ;;
    leavegroup)
        cmdline="rpcfctl leavegroup <group name> <user name>"
        if [[ $# -lt 2 ]]; then
            echo "Error: Missing argument" 
            echo $cmdline
            exit 1
        fi
        bash $cmddir/rpcfmodu.sh -ig $1 $2
        ;;
    addgroup)
        cmdline="rpcfctl addgroup <group name>"
        if [[ $# -lt 1 ]]; then
            echo "Error: Missing argument" 
            echo $cmdline
            exit 1
        fi
        bash $cmddir/rpcfaddg.sh $@
        ;;
    rmgroup)
        cmdline="rpcfctl rmgroup <group name>"
        if [[ $# -lt 1 ]]; then
            echo "Error: Missing argument" 
            echo $cmdline
            exit 1
        fi
        bash $cmddir/rpcfrmg.sh $@
        ;;
    showgroup)
        cmdline="rpcfctl showgroup <group name>"
        if [[ $# -lt 1 ]]; then
            echo "Error: Missing argument" 
            echo $cmdline
            exit 1
        fi
        bash $cmddir/rpcfshow.sh -g $1
        ;;
    listgroup)
        cmdline="rpcfctl listgroup"
        bash $cmddir/rpcfshow.sh -r
        ;;
    authmech)
        cmdline="rpcfctl authmech"
        drvpath=$cfgPath/driver.json
        _mech=`python3 $cmddir/authmech.py $drvpath`
        if [[ "x$_mech" == "x" ]]; then
            echo None
            exit 1;
        else
            echo $_mech
        fi
        ;;
    geninitcfg)
        cmdline="rpcfctl geninitcfg [-c] [<output file>]"
        drvpath=$cfgPath/driver.json
        python3 $cmddir/geninitcfg.py $drvpath $@
        ;;
    updcfg)
        # this commands update the rpc-frmwrk settings only
        # it is convenient to update initcfg.json manually
        # and then use this command to apply the settings 
        # to rpc-frmwrk
        cmdline="rpcfctl updcfg <path to initcfg>"
        if [[ $# -lt 1 ]]; then
            echo "Error: Missing argument" 
            echo $cmdline
            exit 1
        fi
        python3 $cmddir/updcfg.py $@
        ;;
    cfgnui)
        # this commands update not only rpc-frmwrk settings,
        # but webserver and kerebros settings as well.
        cmdline="rpcfctl cfgnui <init config file>"
        if [[ $# -lt 1 ]]; then
            echo "Error: Missing argument" 
            echo $cmdline
            exit 1
        fi
        python3 $cmddir/rpcfgnui.py $@
        ;;
    cfgweb)
        #updating webserver config, nginx or apache
        rpcfctl geninitcfg > /tmp/initcfg.json
        python3 $cmddir/updwscfg.py /tmp/initcfg.json
        #rm /tmp/initcfg.json
        ;;
    cfgkrb5)
        #updating kerberos config
        authMech=`rpcfctl authmech | tr -d ' \t\n\r'`
        if [[ "x$authMech" != "xkrb5" ]]; then
            echo "Kerberos is not current authentication mechanism"
            exit 1
        fi
        pushd $cmddir
        rpcfctl geninitcfg > /tmp/initcfg.json
        python3 -c 'import sys; from updk5cfg import ConfigAuthServer; ConfigAuthServer(sys.argv[1]))' "/tmp/initcfg.json"
        rm /tmp/initcfg.json
        popd
        ;;
    login)
        mech_=`rpcfctl authmech | tr -d ' \t\n\r'`
        if [[ "x$mech_" == "xSimpAuth" ]]; then
            cmdline="rpcfctl login <username name>"
            if [[ $# -lt 1 ]]; then
                echo "Error: Missing argument" 
                echo $cmdline
                exit 1
            fi
            $cmddir/sinit -s $1
        elif [[ "x$mech_" == "xOAuth2" ]]; then
            cmdline="rpcfctl login <auth url>"
            if [[ $# -lt 1 ]]; then
                echo "Error: Missing argument" 
                echo $cmdline
                exit 1
            fi
            python3 -m oinit $1
        elif [[ "x$mech_" == "xkrb5" ]]; then
            cmdline="rpcfctl login <user name>"
            if [[ $# -lt 1 ]]; then
                echo "Error: Missing argument" 
                echo $cmdline
                exit 1
            fi
            kinit -kt $HOME/rpcf/krb5cli.keytab $1
        fi
        ;;
    backup)
        cmdline="rpcfctl backup"
        if rpcfctl list | grep online > /dev/null; then
            echo Error some applications are still running.
            echo $cmdline
            echo The backup file will be stored in the home directory.
            exit 1
        fi
        rpcfctl geninitcfg > ~/.rpcf/cfgbk.json
        tarfile=`realpath rpcf-backup-$(date +%Y%m%d).tar.gz`
        pushd $HOME > /dev/null
        if tar cf "$tarfile" .rpcf; then
            ret=0
        else
            ret=1
        fi
        popd > /dev/null
        if (( $ret == 0 )); then
            echo Successfully generated the backup tarball $tarfile.
        else
            echo Error generating the backup tarball.
        fi
        ;;
    restore)
        cmdline="rpcfctl restore <path to backup file>"
        if [[ $# -lt 1 ]]; then
            echo "Error: Missing the backup package to restore" 
            echo $cmdline
            exit 1
        fi
        tarfile=`realpath "$1"`
        if [[ ! -f "$tarfile" ]]; then
            echo "Error: invalid backup package"
            exit 1
        fi
        pushd $HOME > /dev/null
        if [[ -d .rpcf ]]; then
            echo "Warning: directory .rpcf will be overritten, continue(y/N)?"
            read answer
            if [ "x$answer" == "x" ] || [ "x$answer" == "xno" ] || [[ "x$answer" == "xNo" ]]; then
                popd > /dev/null
                exit 0
            fi
        fi
        if ! tar xf $tarfile; then
            echo "Error: invalid backup package"
            popd > /dev/null
            exit 1
        fi
        if ! cd .rpcf; then
            echo "Error, .rpcf directory does not exist"
            popd > /dev/null
            exit 1
        fi
        if [[ ! -f cfgbk.json ]]; then
            echo "Error, did not find the config backup file"
            popd > /dev/null
            exit 1
        fi
        if [[ "x$(whoami)" == "xroot" ]];then
            SUDOCMD=
        elif which sudo > /dev/null; then
            SUDOCMD=sudo
        fi
        $SUDOCMD python3 $cmddir/rpcfgnui.py ./cfgbk.json
        echo Restore completed successfully
        popd > /dev/null
        ;;
    backuplog)
        cmdline="rpcfctl backuplog <appName> <point name>"
        if [[ $# -lt 2 ]]; then
            echo "Error: requiring 'appname' and 'point name' to do backup"
            echo $cmdline
            exit 1
        fi
        appName="$1"
        ptName="$2"
        if check_appreg_mount; then
            logdir=${rootdir}/apps/$appName/points/$ptName/logs
            while true; do
                if ! grant_perm ${rootdir}/apps/$appName 0005 300; then
                    break
                fi
                if ! grant_perm ${rootdir}/apps/$appName/points 0005 301; then
                    break
                fi
                if ! grant_perm $logdir/.. 0005 302; then
                    break
                fi
                if ! grant_perm $logdir 0007 303; then
                    break
                fi
                chmod o+r $logdir/*
                python3 $cmddir/logtool.py -b --root "${rootdir}" "$appName/$ptName"
                chmod o-r $logdir/*
                break
            done
            restore_perm 303 302 301 300
            undo_check_appreg_mount
        fi
        ;;
    rotatelog)
        cmdline="rpcfctl rotatelog <appName> <point name>"
        if [[ $# -lt 2 ]]; then
            echo "Error: requiring 'appname' and 'point name' to do rotation"
            echo $cmdline
            exit 1
        fi
        appName="$1"
        ptName="$2"
        if check_appreg_mount; then
            logdir=${rootdir}/apps/$appName/points/$ptName/logs
            while true; do
                if ! grant_perm ${rootdir}/apps/$appName 0005 300; then
                    break
                fi
                if ! grant_perm ${rootdir}/apps/$appName/points 0005 301; then
                    break
                fi
                if ! grant_perm $logdir/.. 0005 302; then
                    break
                fi
                if ! grant_perm $logdir 0007 303; then
                    break
                fi
                chmod o+rw $logdir/*
                python3 $cmddir/logtool.py -r --root "${rootdir}" "$appName/$ptName"
                chmod o-rw $logdir/*
                break
            done
            restore_perm 303 302 301 300
            undo_check_appreg_mount
        fi
        ;;
    listlog)
        cmdline="rpcfctl listlog <appName> <point name>"
        if [[ $# -lt 2 ]]; then
            echo "Error: requiring 'appname' and 'point name' to list"
            echo $cmdline
            exit 1
        fi

        appName="$1"
        ptName="$2"
        if check_appreg_mount; then
            logdir=${rootdir}/apps/$appName/points/$ptName/logs
            while true; do
                if ! grant_perm ${rootdir}/apps/$appName 0005 300; then
                    break
                fi
                if ! grant_perm ${rootdir}/apps/$appName/points 0005 301; then
                    break
                fi
                if ! grant_perm $logdir/.. 0005 302; then
                    break
                fi
                if ! grant_perm $logdir 0007 303; then
                    break
                fi
                python3 $cmddir/logtool.py -l --root "${rootdir}" "$appName/$ptName"
                break
            done
            restore_perm 303 302 301 300
            undo_check_appreg_mount
        fi
        ;;
    enablelog)
        cmdline="rpcfctl enablelog <appName> <point name>"
        if [[ $# -lt 2 ]]; then
            echo "Error: requiring 'appname' and 'point name' to enable log for"
            echo $cmdline
            exit 1
        fi
        appName="$1"
        ptName="$2"
        if is_app_online appmonsvr1; then
            echo "Error appmonsvr1 is still onlne, please stop it first"
            exit 1
        fi
        if bash $cmddir/addloglink.sh $@; then
            if is_app_online loggersvr1; then
                rpcf_sendlog -f rpcfctl -l 254 -t INFO -n rpcfctl -p $$ "added loglink $1/$2 from rpcfctl"
            fi
        fi
        ;;
    disablelog)
        cmdline="rpcfctl disablelog <appName> <point name>"
        if [[ $# -lt 2 ]]; then
            echo "Error: requiring 'appname' and 'point name' to disable log for."
            echo $cmdline
            exit 1
        fi
        appName="$1"
        ptName="$2"
        if is_app_online appmonsvr1; then
            echo "Error appmonsvr1 is still onlne, please stop it first"
            exit 1
        fi
        if bash $cmddir/rmloglink.sh $@; then
            if is_app_online loggersvr1; then
                rpcf_sendlog -f rpcfctl -l 254 -t INFO -n rpcfctl -p $$ "removed loglink $1/$2 from rpcfctl"
            fi
            bash $cmddir/setattr.sh $appName $ptName logcount i 0
        fi
        ;;
    clearmount)
        clear_rpcf_mount
        exit $?
        ;;
    chappowner)
        cmdline="rpcfctl chown <appName> <owner> [<group>] "
        if [[ $# -lt 2 ]]; then
            echo Error missing parameters
            echo $cmdline
            exit 1
        fi
        if check_appreg_mount; then
            pushd ${rootdir} > /dev/null
            change_application_owner $@
            popd > /dev/null
            undo_check_appreg_mount
        fi
        ;;
    chptowner)
        cmdline="rpcfctl chown <appName> <pointname> <owner> [<group>]"
        if [[ $# -lt 3 ]]; then
            echo Error missing parameters
            echo $cmdline
            exit 1
        fi
        if check_appreg_mount; then
            pushd ${rootdir} > /dev/null
            change_point_owner $@
            popd > /dev/null
            undo_check_appreg_mount
        fi
        ;;
    geninstaller)
        cmdline="rpcfctl geninstaller <initcfg path> <dest path> <directory of rpc-frmwrk deb/rpm>"
        if [[ $# -lt 2 ]]; then
            echo Error missing parameters
            echo $cmdline
            exit 1
        fi
        python3 $cmddir/buildinst.py $@
        ;;
    *)
        echo "Unknown command: $cmd"
        usage
        exit 1
        ;;
esac
